home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / QuickDraw™ GX / Programming Stuff / Sample Code / Graphics Samples / Offscreen Animation ƒ / Offscreen Animation.c next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  11.7 KB  |  465 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    Offscreen Animation                                        */
  4. /*                                                                            */
  5. /*    Description:    This sample shows how to use the QuickDraw™ GX          */
  6. /*                    offscreenlibrary to perform simple animation.            */
  7. /*                                                                            */
  8. /*    Files:            Offscreen Animation.π                                    */
  9. /*                    Offscreen Animation.c                                    */
  10. /*                                                                            */
  11. /*    Programmer:        Edgar Lee                                                */
  12. /*    Organization:    Apple Computer, Inc.                                    */
  13. /*    Department:        Developer Technical Support, DTS                        */
  14. /*    Language:        C (Think C version 6.0)                                    */
  15. /*    Date Created:    12-13-92                                                */
  16. /*                                                                            */
  17. /*    Change History: 9/93: Updated to run with QuickDraw GX ß2 "GXified"        */
  18. /*                          interface files    - PLA                            */
  19. /*                                                                            */
  20. /****************************************************************************/
  21.  
  22. #include <Desk.h>
  23. #include <Events.h>
  24. #include <Fonts.h>
  25. #include <Windows.h>
  26. #include <Memory.h>
  27. #include <ToolUtils.h>
  28. #include <OSEvents.h>
  29. #include <Quickdraw.h>
  30.  
  31. #include "graphics toolbox.h"
  32. #include "graphics routines.h"
  33. #include "graphics libraries.h"
  34. #include "graphics debugging.h"
  35. #include "qd library.h"
  36. #include "offscreen library.h"
  37.  
  38. /*-----------------------------------------------------------------------------------*/
  39.  
  40. /*************************/
  41. /* Constant Declarations */
  42. /*************************/
  43.  
  44. #define    kWinWidth        400        /* The window width. */
  45. #define    kWinHeight        300        /* The window height. */
  46.  
  47. #define kWinLeft        (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - kWinWidth) / 2)
  48. #define kWinTop            (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - kWinHeight) / 2)
  49.  
  50. #define    kMaxObjects        100        /* Total moving objects in offscreen. */
  51.  
  52. typedef    struct {
  53.     gxShape    shape;
  54.     int        xdelta;
  55.     int        ydelta;
  56. } movingObjectType;
  57.  
  58. /*******************************/
  59. /* Global Variable Definitions */
  60. /*******************************/
  61.  
  62. WindowPtr            gWindow;                        /* The cgrafport. */
  63. offscreen            gOffscreen;
  64.  
  65. gxShape                gTheBackground;                    /* The offscreen background. */
  66. movingObjectType    gMovingObject[kMaxObjects];        /* The moving offscreen objects. */
  67.  
  68. void    initMac(void);                                /* Initializes the mac. */
  69. void    createWindow(void);                            /* Initializes the window's cgrafport. */
  70. void    doEventLoop(void);                            /* Handles events. */
  71.  
  72. void    createOffscreen(void);                        /* Creates a GX offscreen. */
  73. void    initializeShapes(void);                        /* Initializes the shapes used in the offscreen. */
  74. void    updateOffscreen(void);                        /* Updates the position of the moving shapes. */
  75. void    drawOffscreen(void);                        /* Draw the offscreen to the window. */
  76. void    disposeOffscreen(void);                        /* Disposes the memory used for the offscreen. */
  77.  
  78. int        randomInteger(int min, int max);            /* Returns a random integer. */
  79. int        randomSignInteger(int start,int end);        /* Returns a variation of randomInteger. */
  80. int        absInteger(int num);                        /* Returns the absolute value. */
  81. void    getRandomColor(long    *r,long *g,long *b);    /* Returns a random old QD gxColor. */
  82.  
  83. /*-----------------------------------------------------------------------------------*/
  84.  
  85. main()
  86. {
  87.     gxGraphicsClient     client;
  88.     
  89.     initMac();
  90.  
  91.     client = GXNewGraphicsClient( nil, 2000L * 1024, 0L );
  92.     
  93.     createWindow();
  94.     
  95.     createOffscreen();
  96.     initializeShapes();
  97.     
  98.     doEventLoop();
  99.     
  100.     disposeOffscreen();
  101.     GXDisposeGraphicsClient( client );
  102. }
  103.  
  104. /*-----------------------------------------------------------------------------------*/
  105.  
  106. void initMac()
  107. {
  108.     MaxApplZone();
  109.     MoreMasters (); MoreMasters (); MoreMasters (); MoreMasters ();
  110.  
  111.     InitGraf( &qd.thePort );
  112.     InitFonts();
  113.     InitWindows();
  114.     /***
  115.     InitMenus();
  116.     TEInit();
  117.     InitDialogs( nil );***/
  118.     InitCursor();
  119.     FlushEvents( 0, everyEvent );
  120.     
  121.     qd.randSeed = TickCount();
  122. }
  123.  
  124. /*-----------------------------------------------------------------------------------*/
  125.  
  126. void createWindow()
  127. {
  128.     Rect    rect;
  129.     
  130.     SetRect( &rect, kWinLeft, kWinTop, kWinLeft + kWinWidth, kWinTop + kWinHeight );
  131.     gWindow = NewCWindow( 0L, &rect, "\pOffscreen Animation", true, documentProc,
  132.                             (WindowPtr)-1L, true, 0L );                        
  133.     SetPort( gWindow );
  134.     SetDefaultViewPort( GXNewWindowViewPort( gWindow ) );
  135. }
  136.  
  137. /*-----------------------------------------------------------------------------------*/
  138.  
  139. void initializeShapes()
  140. {
  141.     int            i;
  142.     int            radius, minRadius, maxRadius;
  143.     long        red, green, blue;
  144.     float        brightnessFactor;
  145.     gxRectangle     bgRectData = { ff( 0 ), ff( 0 ), ff( kWinWidth ), ff( kWinHeight ) };    
  146.     gxRectangle     objectRectData;
  147.     
  148.     /******************************************************/
  149.     /* Initialize the background shape for the offscreen. */
  150.     /******************************************************/
  151.  
  152.     gTheBackground = GXNewRectangle( &bgRectData );
  153.     GXSetShapeTransform( gTheBackground, gOffscreen.xform );
  154.     SetShapeRGB( gTheBackground, 0, 0, 0 );
  155.  
  156.     /**************************************************/
  157.     /* Initialize the moving shapes in the offscreen. */
  158.     /**************************************************/
  159.     
  160.     for (i = 0; i < kMaxObjects; i++)
  161.     {
  162.         /***************************************/
  163.         /* Define the shape's movement offset. */
  164.         /***************************************/
  165.         
  166.         if (i < (2 * kMaxObjects) / 3)
  167.         {
  168.             minRadius = 1;
  169.             maxRadius = 3;
  170.         }
  171.         else if (i >= (2 * kMaxObjects) / 3 && i < (7 * kMaxObjects) / 8)
  172.         {
  173.             minRadius = 4;
  174.             maxRadius = 6;
  175.         }
  176.         else if (i >= (7 * kMaxObjects) / 8 && i < kMaxObjects)
  177.         {
  178.             minRadius = 7;
  179.             maxRadius = 10;
  180.         }
  181.             
  182.         gMovingObject[i].xdelta    = randomSignInteger( minRadius, maxRadius );
  183.         gMovingObject[i].ydelta    = randomSignInteger( minRadius, maxRadius );
  184.  
  185.         /****************************/
  186.         /* Define the shape's size. */
  187.         /****************************/
  188.         
  189.         if (absInteger( gMovingObject[i].xdelta ) >= absInteger( gMovingObject[i].ydelta ))
  190.             radius = absInteger( gMovingObject[i].xdelta );
  191.         else
  192.             radius = absInteger( gMovingObject[i].ydelta );
  193.             
  194.         objectRectData.left        = ff( randomInteger( 1, kWinWidth ) );
  195.         objectRectData.top        = ff( randomInteger( 1, kWinHeight ) );
  196.         objectRectData.right    = objectRectData.left + ff( radius );
  197.         objectRectData.bottom    = objectRectData.top + ff( radius );
  198.         
  199.         gMovingObject[i].shape    = GXNewRectangle( &objectRectData );
  200.         GXSetShapeTransform( gMovingObject[i].shape, gOffscreen.xform );
  201.  
  202.         /*****************************/
  203.         /* Define the shape's gxColor. */
  204.         /*****************************/
  205.         
  206.         brightnessFactor = (float)radius / 10.;
  207.         getRandomColor( &red, &green, &blue );
  208.                 
  209.         SetShapeRGB( gMovingObject[i].shape, red * brightnessFactor,
  210.                     green * brightnessFactor, blue * brightnessFactor );
  211.     }
  212. }
  213.  
  214. /*-----------------------------------------------------------------------------------*/
  215.  
  216. void createOffscreen()
  217. {
  218.     Rect        rect;
  219.     gxBitmap    bm;
  220.     gxShape        offscreenShape;
  221.  
  222.     rect = (*gWindow).portRect;
  223.     
  224.     bm.width        = rect.right - rect.left;
  225.     bm.height        = rect.bottom - rect.top;
  226.     bm.pixelSize    = 8;
  227.     bm.rowBytes        = 0;
  228.     bm.space        = gxIndexedSpace;
  229.     bm.set            = CTableToColorSet( GetCTable( 8 ) );
  230.     bm.profile        = nil;
  231.     bm.image        = nil;
  232.     
  233.     offscreenShape = GXNewBitmap( &bm, nil );
  234.     CreateOffscreen( &gOffscreen, offscreenShape );
  235. }
  236.  
  237. /*-----------------------------------------------------------------------------------*/
  238.  
  239. void updateOffscreen()
  240. {
  241.     int            i;
  242.     fixed        xpos, ypos;
  243.     fixed        xdelta, ydelta;
  244.     gxRectangle    bounds;
  245.     gxViewPort    savedViewPort;
  246.  
  247.     /**********************************************************/
  248.     /* Draw the background shape to erase the previous image. */
  249.     /**********************************************************/
  250.  
  251.     GXDrawShape( gTheBackground );
  252.  
  253.     /***************************************************/
  254.     /* Draw the moving objects in their new positions. */
  255.     /***************************************************/
  256.  
  257.     for (i = 0; i < kMaxObjects; i++)
  258.     {
  259.         GXDrawShape( gMovingObject[i].shape );
  260.         
  261.         GXGetShapeBounds( gMovingObject[i].shape, 0L, &bounds );
  262.         
  263.         xpos = bounds.left;
  264.         ypos = bounds.top;
  265.         
  266.         xdelta = ff( gMovingObject[i].xdelta / 2 );
  267.         ydelta = ff( gMovingObject[i].ydelta / 2 );
  268.         
  269.         /***************************************************/
  270.         /* If the object goes beyond the offscreen bounds, */
  271.         /*   make it go in the opposite direction.         */
  272.         /***************************************************/
  273.  
  274.         if (xpos + xdelta >= ff( kWinWidth ) || xpos + xdelta <= ff( 0 ))
  275.             gMovingObject[i].xdelta = -gMovingObject[i].xdelta;
  276.         
  277.         if (ypos + ydelta >= ff( kWinHeight ) || ypos + ydelta <= ff( 0 ))
  278.             gMovingObject[i].ydelta = -gMovingObject[i].ydelta;
  279.     
  280.         GXMoveShapeTo( gMovingObject[i].shape, xpos + xdelta, ypos + ydelta );
  281.     }
  282. }
  283.  
  284. /*-----------------------------------------------------------------------------------*/
  285.  
  286. void disposeOffscreen()
  287. {
  288.     DisposeOffscreen( &gOffscreen );
  289. }
  290.  
  291. /*-----------------------------------------------------------------------------------*/
  292.  
  293. void drawOffscreen()
  294. {
  295.     GXDrawShape( gOffscreen.draw );
  296. }
  297.  
  298. /*-----------------------------------------------------------------------------------*/
  299.  
  300. void doEventLoop()
  301. {
  302.     EventRecord     event;
  303.     WindowPtr       window;
  304.     short           clickArea;
  305.     Rect            screenRect;
  306.     long            ticks = 0;
  307.     
  308.     for (;;)
  309.     {
  310.         /************************************************/
  311.         /* Update the offscreen once every 1/30 second. */
  312.         /************************************************/
  313.  
  314.         if (TickCount() - ticks > 2)
  315.         {
  316.             updateOffscreen();
  317.             drawOffscreen();
  318.             ticks = TickCount();
  319.         }
  320.  
  321.         /***************************/
  322.         /* Handle incoming events. */
  323.         /***************************/
  324.         
  325.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  326.         {
  327.             if (event.what == mouseDown)
  328.             {
  329.                 clickArea = FindWindow( event.where, &window );
  330.                 
  331.                 if (clickArea == inDrag)
  332.                 {
  333.                     screenRect = (**GetGrayRgn()).rgnBBox;
  334.                     DragWindow( window, event.where, &screenRect );
  335.                 }
  336.                 else if (clickArea == inContent)
  337.                 {
  338.                     if (window != FrontWindow())
  339.                         SelectWindow( window );
  340.                 }
  341.                 else if (clickArea == inGoAway)
  342.                     if (TrackGoAway( window, event.where ))
  343.                         return;
  344.             }
  345.             else if (event.what == updateEvt)
  346.             {
  347.                 window = (WindowPtr)event.message;    
  348.                 SetPort( window );
  349.                 
  350.                 BeginUpdate( window );
  351.                 drawOffscreen();
  352.                 EndUpdate( window );
  353.             }
  354.         }
  355.     }
  356. }
  357.  
  358. /*-----------------------------------------------------------------------------------*/
  359.  
  360. int absInteger( num )
  361. int        num;
  362. {
  363.     int        absolute;
  364.     
  365.     absolute = num;
  366.     
  367.     if (absolute < 0)
  368.         absolute = -absolute;
  369.         
  370.     return absolute;
  371. }
  372.  
  373. /*-----------------------------------------------------------------------------------*/
  374.  
  375. int    randomInteger( min, max )
  376. int        min, max;
  377. {
  378.     long     randomNum;
  379.  
  380.     randomNum = Random();
  381.         
  382.     if (min >= 0 && max >= 0)
  383.     {
  384.         if (randomNum < 0)
  385.             randomNum = -randomNum;
  386.     }
  387.     
  388.     randomNum = ((randomNum * (max - min)) / 32767) + min;
  389.     
  390.     return randomNum;
  391. }
  392.  
  393. /*-----------------------------------------------------------------------------------*/
  394.  
  395. int    randomSignInteger( start, end )
  396. int        start, end;
  397. {
  398.     long    randomNum;
  399.     int        sign = 1;
  400.         
  401.     if ((randomNum = Random()) < 0)
  402.     {
  403.         randomNum = -randomNum;
  404.         sign = -1;
  405.     }
  406.  
  407.     randomNum = (((randomNum * (end - start)) / 32767) + start) * sign;
  408.             
  409.     return randomNum;
  410. }
  411.  
  412. /*-----------------------------------------------------------------------------------*/
  413.  
  414. void getRandomColor( r, g, b )
  415. long    *r, *g, *b;
  416. {
  417.     long    randomNum;
  418.     int        choice;
  419.     
  420.     randomNum = Random();
  421.     choice = absInteger( (randomNum * 7) / 32767 );
  422.     
  423.     if (choice == 0)                /*** red ***/
  424.     {
  425.         *r = 0xffff;
  426.         *g = 0;
  427.         *b = 0;
  428.     }
  429.     else if (choice == 1)            /*** green ***/
  430.     {
  431.         *r = 0;
  432.         *g = 0xffff;
  433.         *b = 0;
  434.     }
  435.     else if (choice == 2)            /*** blue ***/
  436.     {
  437.         *r = 0;
  438.         *g = 0;
  439.         *b = 0xffff;
  440.     }
  441.     else if (choice == 3)            /*** yellow ***/
  442.     {
  443.         *r = 0xffff;
  444.         *g = 0xffff;
  445.         *b = 0;
  446.     }
  447.     else if (choice == 4)            /*** magenta ***/
  448.     {
  449.         *r = 0xffff;
  450.         *g = 0;
  451.         *b = 0xffff;
  452.     }
  453.     else if (choice == 5)            /*** cyan ***/
  454.     {
  455.         *r = 0;
  456.         *g = 0xffff;
  457.         *b = 0xffff;
  458.     }
  459.     else if (choice == 6)            /*** white ***/
  460.     {
  461.         *r = 0xffff;
  462.         *g = 0xffff;
  463.         *b = 0xffff;
  464.     }
  465. }